package com.kuangshenJVM.chapter14;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MyClassLoader extends ClassLoader {
    //类加载器名称
    private String name;
    //类存放路径
    private String path;

    public void setPath(String path){
        this.path = path;
    }

    MyClassLoader(String name){
        this.name = name;
    }

    public MyClassLoader(ClassLoader parent, String name) {
        super(parent);
        this.name = name;
    }
    //查找名称为 name 的类，返回值是 java.lang.Class类的实例
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        //找到对应的字节码
        byte[] data = new byte[0];
        try {
            data = getDatas(name);
        } catch (IOException e) {
            e.printStackTrace();
        }
//        通过字节码生成相应的实例
        return this.defineClass(name,data,0, data.length);
    }
    //读取Class字节流
    private byte[] getDatas(String name) throws IOException {
        name = name.replace(".", "/");
        File file = new File(path + name + ".class");
        System.out.println("加载二进制文件：" + file.getPath());
        FileInputStream in = null;
        ByteArrayOutputStream outputStream = null;
        if (file.exists()) {
            try {
                in = new FileInputStream(file);
                outputStream = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int size = 0;
                while ((size = in.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, size);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                in.close();
            }
            return outputStream.toByteArray();
        }
        return null;
    }
}

class ClassLoaderTest{
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        //新建一个类加载器
        MyClassLoader myClassLoader = new MyClassLoader("myClassLoader");
        //类存放的根路径 ；out/production/kuangshenJVM
        // 在com.xx.xxx之前
        myClassLoader.setPath("out/production/kuangshenJVM/");

        //查找名为name的类，返回的结果是 java.lang.Class类的实例
        Class<?> aClass = myClassLoader.findClass("com.kuangshenJVM.chapter14.Hello");
        System.out.println("hello 的加载器 ： " + aClass.getClassLoader());

        Class<?> double02 = myClassLoader.findClass("com.kuangshenJVM.chapter14.Double");
         System.out.println("double02 的加载器 ： " + double02.getClassLoader());

        Method main = aClass.getDeclaredMethod("main", String[].class);
        Object o = aClass.newInstance();
        String[] strings = {};
        main.invoke(o,(Object) strings);
    }
}


